////////////////////////////////////////////////////////////////////////////
//
//  CryEngine Source File.
//  Copyright (C), Crytek, 1999-2010.
// -------------------------------------------------------------------------
//  File name:	AssetBrowserDialog.cpp
//  Version:	v1.00
//  Created:	30/07/2008 by Paulo Zaffari
//  Description:	Implementation of AssetBrowserDialog.h
// -------------------------------------------------------------------------  
//  History:
//		30/07/2008  17:24 - Paulo Zaffari - created
//		12/03/2010  12:48 - Nicusor Nedelcu - refactored
//
//////////////////////////////////////////////////////////////////////////// 

#include "stdafx.h"
#include "AssetBrowserDialog.h"
#include "Include/IAssetDisplayDatabase.h"
#include "Visual Budget System/VisualBudgetSystem.h"
#include "Include/IAssetDisplay.h"
#include "Asset Browser/AssetBrowserFilterPresetsDlg.h"
#include "Objects/EntityObject.h"
#include "AssetMetaDataFileDB.h"
#include "Dialogs/Generic/ProgressDialog.h"
#include "Util/IndexedFiles.h"
#include "Objects/BrushObject.h"
#include "Console/ConsoleHotUpdate.h"
#include "ViewManager.h"

#define IDC_DOCKING_PANE					1000
#define IDC_BUDGET_PANE						1001
#define IDW_ASSET_BROWSER_LIST_VIEW_PANE ( AFX_IDW_CONTROLBAR_FIRST + 100 )
#define IDW_ASSET_BROWSER_PREVIEW_PANE ( AFX_IDW_CONTROLBAR_FIRST + 103 )
#define ASSET_BROWSER_BYTES_TO_MBYTES( nBytes ) ( (float)nBytes / 1024.0f / 1024.0f )

namespace AssetBrowser
{
	const COLORREF	kListViewOddRowColor = RGB( 235, 235, 235 );
	const COLORREF	kListViewSelectedRowColor = RGB( 215, 215, 0 );
	const UINT			kSearchEditDialogHeight = 33;
	const UINT			kReportCtrl_CacheTimerDelay = 50;
	const char*			kNoPresetText = "(No preset)";
	const UINT			kFilterPresetsComboLengthInPixels = 250;
	const UINT			kOneMegaByte = 1048576;
	const UINT			kOneKiloByte = 1024;
	const bool			kAssetMetadataCachingIsOnThread = false;
};

//! This class is used as a virtual record handler, this will be set into the list view and it will provide data for the list
class CAssetListVirtualRecord : public CXTPReportRecord
{
	public:

		CAssetListVirtualRecord( CAssetBrowserDialog* pDlg, std::vector<IAssetDisplay*>* pcAssets = NULL );
		void GetItemMetrics( XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, XTP_REPORTRECORDITEM_METRICS* pItemMetrics );

		//! current assets in the viewer
		std::vector<IAssetDisplay*>*	m_pAssets;
		//! the asset browser dialog
		CAssetBrowserDialog*					m_pAssetBrowserDlg;
		//! A saved top row index to find out if the list view has been scrolled
		int														m_prevTopRowIndex;
};	

//! This class handles asset browser list view clicks/sort on list header
class CAssetListReportHeader : public CXTPReportHeader
{
	public:

		CAssetListReportHeader(CAssetBrowserDialog* pAssetBrowserDlg, CXTPReportControl* pCtrl, CXTPReportColumns* pCols );
		void OnLButtonUp(UINT nFlags, CPoint ptClick);

		CAssetBrowserDialog* m_pAssetBrowserDlg;
};

//! This is the class which will expose the asset browser as a view tool
class CAssetBrowserViewClass : public TRefCountBase<IViewPaneClass>
{
	//////////////////////////////////////////////////////////////////////////
	// IClassDesc
	//////////////////////////////////////////////////////////////////////////
	virtual ESystemClassID SystemClassID() { return ESYSTEM_CLASS_VIEWPANE; };
	virtual REFGUID ClassID()
	{
		// {48903B8B-7269-4ffa-80EF-46E9E531CE85}
		static const GUID guid = { 0x48903b8b, 0x7269, 0x4ffa, { 0x80, 0xef, 0x46, 0xe9, 0xe5, 0x31, 0xce, 0x85 } };
		return guid;
	}

	virtual const char*				ClassName() { return "Asset Browser"; };
	virtual const char*				Category() { return "Asset Browser"; };
	virtual CRuntimeClass*		GetRuntimeClass() { return RUNTIME_CLASS( CAssetBrowserDialog ); };
	virtual const char*				GetPaneTitle() { return _T("Asset Browser"); };
	virtual EDockingDirection	GetDockingDirection() { return DOCK_FLOAT; };
	virtual CRect							GetPaneRect() { return CRect( 100, 80, 1400, 850 ); };
	virtual bool							SinglePane() { return true; };
	virtual bool							WantIdleUpdate() { return true; };
};

CAssetListReportHeader::CAssetListReportHeader(CAssetBrowserDialog* pAssetBrowserDlg, CXTPReportControl* pCtrl, CXTPReportColumns* pCols ) : CXTPReportHeader( pCtrl, pCols )
{
	m_pAssetBrowserDlg = pAssetBrowserDlg;
}

void CAssetListReportHeader::OnLButtonUp(UINT nFlags, CPoint ptClick)
{
	__super::OnLButtonUp( nFlags, ptClick );
	CString str;

	CXTPReportColumn* pColumn = HitTest( ptClick );

	if( pColumn && m_pAssetBrowserDlg )
	{
		m_pAssetBrowserDlg->SortAssets( pColumn->GetInternalName(), pColumn->IsSortedDecreasing() );
	}
}

//---

BEGIN_MESSAGE_MAP(CAssetBrowserReportControl, CXTPReportControl)
	ON_WM_CREATE()
	ON_WM_TIMER()
END_MESSAGE_MAP()

CAssetBrowserReportControl::CAssetBrowserReportControl() : CXTPReportControl()
{
	m_pAssetBrowserDlg = NULL;
}

void CAssetBrowserReportControl::OnSelectionChanged()
{
	assert( m_pAssetBrowserDlg );
	UINT index = 0;

	if( !m_pAssetBrowserDlg )
		return;

	if( !GetSelectedRows() )
	{
		m_pAssetBrowserDlg->m_bSelectAssetsFromListView = true;
		m_pAssetBrowserDlg->m_oAssetViewer.DeselectAll();
		return;
	}

	m_pAssetBrowserDlg->m_oAssetViewer.LockAssetItemsArray();
	bool bHasItems = !m_pAssetBrowserDlg->m_oAssetViewer.GetAssetItems().empty();
	m_pAssetBrowserDlg->m_oAssetViewer.UnlockAssetItemsArray();

	if( bHasItems )
	{
		POSITION pos = GetSelectedRows()->GetFirstSelectedRowPosition();
		TAssetItems itemsSelected;

		itemsSelected.resize( GetSelectedRows()->GetCount() );
		m_pAssetBrowserDlg->m_oAssetViewer.LockAssetItemsArray();

		for( size_t i = 0, iCount = GetSelectedRows()->GetCount(); i < iCount; ++i )
		{
			UINT idx = GetSelectedRows()->GetAt( i )->GetIndex();

			if( idx >= 0 && idx < m_pAssetBrowserDlg->m_oAssetViewer.GetAssetItems().size() )
			{
				itemsSelected[i] = m_pAssetBrowserDlg->m_oAssetViewer.GetAssetItems()[idx];
			}
		}
		
		m_pAssetBrowserDlg->m_oAssetViewer.UnlockAssetItemsArray();
		m_pAssetBrowserDlg->m_bSelectAssetsFromListView = true;
		m_pAssetBrowserDlg->m_oAssetViewer.SelectAssets( itemsSelected );

		index = (UINT) pos;
		// correct index
		index--;
		m_pAssetBrowserDlg->m_oAssetViewer.LockAssetItemsArray();
		index = CLAMP( index, 0, m_pAssetBrowserDlg->m_oAssetViewer.GetAssetItems().size() );
		m_pAssetBrowserDlg->m_oAssetViewer.UnlockAssetItemsArray();
	}
	else
	{
		m_pAssetBrowserDlg->m_bSelectAssetsFromListView = true;
		m_pAssetBrowserDlg->m_oAssetViewer.DeselectAll( false );
	}

	m_pAssetBrowserDlg->m_oAssetViewer.LockAssetItemsArray();

	if( bHasItems && index >= 0 && index < m_pAssetBrowserDlg->m_oAssetViewer.GetAssetItems().size() )
	{
		m_pAssetBrowserDlg->m_bSelectAssetsFromListView = true;
		m_pAssetBrowserDlg->m_oAssetViewer.EnsureAssetVisible( index, true );
	}

	m_pAssetBrowserDlg->m_oAssetViewer.UnlockAssetItemsArray();
}

int CAssetBrowserReportControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if(CXTPReportControl::OnCreate(lpCreateStruct) == -1) 
		return -1;

	SetTimer( ID_ASSET_BROWSER_TIMER_REPORT_CONTROL, AssetBrowser::kReportCtrl_CacheTimerDelay, NULL );
	return 0;
}

void CAssetBrowserReportControl::OnTimer( UINT_PTR nIDEvent )
{
	if( nIDEvent == ID_ASSET_BROWSER_TIMER_REPORT_CONTROL )
	{
		if( CacheFieldsInfoForVisibleAsset() )
			RedrawControl();
		else
			KillTimer( ID_ASSET_BROWSER_TIMER_REPORT_CONTROL );
	}
}

bool CAssetBrowserReportControl::CacheFieldsInfoForVisibleAsset()
{
	for( size_t nCurrentItem = 0, nTotalItems = m_cVisibleItems.size(); nCurrentItem < nTotalItems; ++nCurrentItem )
	{
		IAssetDisplay* const pItem = m_cVisibleItems[nCurrentItem];

		if(	pItem->IsFlagSet( IAssetDisplay::eAssetFlags_CachedFieldsInfo ) ||
				pItem->IsFlagSet( IAssetDisplay::eAssetFlags_Invalid ) )
		{
			continue;
		}

		pItem->CacheFieldsInfo();

		return true;
	}

	return false;
}

void CAssetBrowserReportControl::ClearVisibleItems()
{
	m_cVisibleItems.clear();
	SetTimer( ID_ASSET_BROWSER_TIMER_REPORT_CONTROL, AssetBrowser::kReportCtrl_CacheTimerDelay, NULL );
}

void CAssetBrowserReportControl::AddVisibleItem(IAssetDisplay *pAsset)
{
	stl::push_back_unique(m_cVisibleItems, pAsset);
}

//---

CAssetListVirtualRecord::CAssetListVirtualRecord( CAssetBrowserDialog* pDlg, std::vector<IAssetDisplay*>* pcAssets )
{
	m_pAssetBrowserDlg = pDlg;
	m_pAssets = pcAssets;
	m_prevTopRowIndex = -1;
}

void CAssetListVirtualRecord::GetItemMetrics( XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, XTP_REPORTRECORDITEM_METRICS* pItemMetrics )
{
	CXTPReportColumnOrder* pSortOrder = pDrawArgs->pControl->GetColumns()->GetSortOrder();
	BOOL bDecreasing = pSortOrder->GetCount() > 0 && pSortOrder->GetAt(0)->IsSortedDecreasing();

	CString strColumn = pDrawArgs->pColumn->GetCaption();
	int nIndexCol = pDrawArgs->pColumn->GetItemIndex();
	int nIndexRow = pDrawArgs->pRow->GetIndex();
	int nCount = pDrawArgs->pControl->GetRows()->GetCount();

	if( m_pAssets )
	{
		if ( m_prevTopRowIndex != m_pAssetBrowserDlg->m_oAssetListView.GetTopRowIndex() )
		{
			// The report view has changed since last time. So we should rebuild the list of visible items.
			m_pAssetBrowserDlg->m_oAssetListView.ClearVisibleItems();
			m_prevTopRowIndex = m_pAssetBrowserDlg->m_oAssetListView.GetTopRowIndex();

			size_t rowIndex = std::min(	m_pAssetBrowserDlg->m_oAssetListView.GetRows()->GetCount(), 
																	m_prevTopRowIndex + m_pAssetBrowserDlg->m_oAssetListView.GetReportAreaRows(m_prevTopRowIndex, TRUE) + 2 );

			rowIndex = std::min( (*m_pAssets).size(), rowIndex );

			for( size_t i = m_prevTopRowIndex; i < rowIndex; ++i )
			{
				if( !(*m_pAssets)[i]->IsFlagSet( IAssetDisplay::eAssetFlags_CachedFieldsInfo ) )
				{
					m_pAssetBrowserDlg->m_oAssetListView.AddVisibleItem( (*m_pAssets)[i] );
				}
			}
		}

		if( nIndexRow < (*m_pAssets).size() )
		{
			pItemMetrics->strText = CAssetViewer::GetAssetFieldDisplayValue( (*m_pAssets)[nIndexRow], pDrawArgs->pColumn->GetInternalName() );
		}

		pItemMetrics->nVirtRowLevel = 0;
		pItemMetrics->nVirtRowFlags |= xtpVirtRowLastChild;
	}

	if( nIndexRow % 2 )
	{
		//TODO: with skinning this will look ackward, see if you can get color from skin/theme
		//pItemMetrics->clrBackground = CGdiCanvas::ScaleColor( pItemMetrics->clrBackground, 0.9f );// AssetBrowser::kListViewOddRowColor;
	}
	
	if( m_pAssets )
	{
		if( nIndexRow < (*m_pAssets).size() )
		{
			if( (*m_pAssets)[nIndexRow]->IsFlagSet( IAssetDisplay::eAssetFlags_Selected ) )
			{
				pItemMetrics->clrBackground = AssetBrowser::kListViewSelectedRowColor;
			}
		}
	}
}

// CAssetBrowserDialog dialog
IMPLEMENT_DYNCREATE(CAssetBrowserDialog,CBaseFrameWnd)

BEGIN_MESSAGE_MAP(CAssetBrowserDialog, CBaseFrameWnd)
	ON_WM_CLOSE()
	ON_WM_DESTROY()
	ON_WM_TIMER()
	ON_WM_SIZE()
	ON_WM_KEYDOWN()

	ON_XTP_EXECUTE( ID_ASSET_BROWSER_FILTER_PRESETS, OnAssetBrowserChangeFilterPresets )
	ON_XTP_EXECUTE( ID_ASSET_BROWSER_THUMB_SIZE, OnAssetBrowserChangeThumbSize )
	ON_COMMAND_RANGE(ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_START,ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_END,OnAssetBrowserDatabase)
	ON_COMMAND( ID_ASSET_BROWSER_DATABASE_CHECK_ALL_DB_BUTTON, OnAssetBrowserDatabaseCheckAll )
	ON_COMMAND( ID_ASSET_BROWSER_DATABASE_UNCHECK_ALL_DB_BUTTON, OnAssetBrowserDatabaseUncheckAll )
	ON_COMMAND( ID_ASSET_BROWSER_DATABASE_REFRESH_DB_BUTTON, OnAssetBrowserDatabaseRefresh )
	ON_COMMAND( ID_ASSET_BROWSER_EDIT_FILTER_PRESETS, OnAssetBrowserEditFilterPresets )
	ON_COMMAND( ID_ASSET_BROWSER_SHOW_USED_IN_VIEWPORT_SELECTION_BUTTON, OnAssetBrowserFromViewportSelection )
	ON_COMMAND( ID_ASSET_BROWSER_SELECT_IN_VIEWPORT_BUTTON, OnAssetBrowserSelectInViewport )
	ON_COMMAND( ID_ASSET_BROWSER_REFRESH_USED_IN_LEVEL, OnAssetBrowserRefreshUsedInLevel )
	ON_COMMAND( ID_ASSET_BROWSER_SHOW_USED_IN_LEVEL, OnAssetBrowserShowUsedInLevel )
	ON_COMMAND( ID_ASSET_BROWSER_SHOW_FAVOURITES, OnAssetBrowserShowFavourites )
	ON_COMMAND( ID_ASSET_BROWSER_HIDE_LODS, OnAssetBrowserHideLods )
	ON_COMMAND( ID_ASSET_BROWSER_AUTO_CHANGE_VIEWPORT_SELECTION, OnAssetBrowserAutoChangeViewportSelection )
	ON_COMMAND( ID_ASSET_BROWSER_AUTO_FILTER_FROM_VIEWPORT_SELECTION, OnAssetBrowserAutoFilterFromViewportSelection )
	ON_COMMAND( ID_ASSET_BROWSER_CLEAR_VIEWPORT_FILTER, OnAssetBrowserClearViewportFilter )
	ON_COMMAND( ID_ASSET_BROWSER_CONSOLE_HOT_UPDATE, OnAssetBrowserConsoleHotUpdateFromSelection )
	ON_COMMAND( ID_VISUAL_BUDGET_UPDATE, OnVisualBudgetUpdate )
	ON_COMMAND( ID_VISUAL_BUDGET_ANALYZE_SINGLE_SECTOR, OnVisualBudgetAnalyzeSingleSector )
	ON_COMMAND( ID_VISUAL_BUDGET_SHOW, OnVisualBudgetDisplaySectors )
	ON_XTP_EXECUTE( ID_VISUAL_BUDGET_CELL_SIZE, OnVisualBudgetChangeCellSize )
	ON_UPDATE_COMMAND_UI_RANGE(ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_START,ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_END,OnUpdateAssetBrowserDatabase)
	ON_UPDATE_COMMAND_UI(ID_ASSET_BROWSER_FILTER_PRESETS,OnUpdateAssetBrowserCtrl)
	ON_UPDATE_COMMAND_UI(ID_ASSET_BROWSER_THUMB_SIZE,OnUpdateAssetBrowserCtrl)
	ON_UPDATE_COMMAND_UI(ID_ASSET_BROWSER_EDIT_TAGS,OnUpdateAssetBrowserCtrl)
	ON_UPDATE_COMMAND_UI(ID_VISUAL_BUDGET_CELL_SIZE,OnUpdateAssetBrowserCtrl)
	ON_UPDATE_COMMAND_UI(ID_ASSET_BROWSER_SHOW_USED_IN_LEVEL, OnUpdateAssetBrowserUsedInLevel)
	ON_UPDATE_COMMAND_UI(ID_ASSET_BROWSER_SHOW_FAVOURITES, OnUpdateAssetBrowserShowFavourites)
	ON_UPDATE_COMMAND_UI(ID_ASSET_BROWSER_HIDE_LODS, OnUpdateAssetBrowserHideLods)
	ON_UPDATE_COMMAND_UI(ID_ASSET_BROWSER_AUTO_CHANGE_VIEWPORT_SELECTION, OnUpdateAssetBrowserAutoChangeViewportSelection)
	ON_UPDATE_COMMAND_UI(ID_ASSET_BROWSER_AUTO_FILTER_FROM_VIEWPORT_SELECTION, OnUpdateAssetBrowserAutoFilterFromViewportSelection)
	ON_UPDATE_COMMAND_UI(ID_VISUAL_BUDGET_ANALYZE_SINGLE_SECTOR, OnUpdateVisualBudgetAnalyzeSingleSector)
	ON_UPDATE_COMMAND_UI(ID_VISUAL_BUDGET_SHOW, OnUpdateVisualBudgetDisplaySectors)
	ON_UPDATE_COMMAND_UI_RANGE(ID_VISUAL_BUDGET_ELEMENT_TERRAIN,ID_VISUAL_BUDGET_ELEMENT_MISC,OnUpdateVisualBudgetElement)
	ON_UPDATE_COMMAND_UI_RANGE(ID_VISUAL_BUDGET_DISPLAY_LINES,ID_VISUAL_BUDGET_DISPLAY_BOXES,OnUpdateVisualBudgetDisplayMode)
	ON_UPDATE_COMMAND_UI_RANGE(ID_VISUAL_BUDGET_RESTYPE_GEOMETRY,ID_VISUAL_BUDGET_RESTYPE_ALL,OnUpdateVisualBudgetResourceType)
	ON_COMMAND_RANGE(ID_VISUAL_BUDGET_ELEMENT_TERRAIN,ID_VISUAL_BUDGET_ELEMENT_MISC,OnVisualBudgetCheckElement)
	ON_COMMAND_RANGE(ID_VISUAL_BUDGET_DISPLAY_LINES,ID_VISUAL_BUDGET_DISPLAY_BOXES,OnVisualBudgetCheckDisplayMode)
	ON_COMMAND_RANGE(ID_VISUAL_BUDGET_RESTYPE_GEOMETRY,ID_VISUAL_BUDGET_RESTYPE_ALL,OnVisualBudgetCheckResourceType)
END_MESSAGE_MAP()

CAssetBrowserDialog* CAssetBrowserDialog::s_poCurrentInstance = NULL;
bool CAssetBrowserDialog::s_bInitialized = false;

CAssetBrowserDialog::CAssetBrowserDialog():
m_roVisualBudgetSystem( CVisualBudgetSystem::GetVisualBudgetSystem() )
{
	CRect rc( 0, 0, 0, 0 );

	m_bSelectAssetsFromListView = false;
	m_pRibbonBar = NULL;
	s_poCurrentInstance = this;
	m_pAssetVirtualRecord = NULL;
	m_pReportHeader = NULL;
	m_pCbThumbSize = NULL;
	m_pCbFilterPresets = NULL;
	m_bShowMergedDatabaseFields = false;
	m_bAutoChangeViewportSelection = false;
	m_bAutoFilterFromViewportSelection = false;

	m_vbsDisplayType = 0;
	m_vbsResourceType = 0;
	m_vbsCellSizeIndex = 0;
	m_bVbsEnabledStatus = false;

	m_pCbThumbSize = NULL;
	m_pCbFilterPresets = NULL;
	m_pChkUsedInLevel = NULL;
	m_pChkLoadedInLevel = NULL;
	m_pChkShowFavourites = NULL;
	m_pChkHideLods = NULL;
	m_pCbVbsCellSize = NULL;

	GetIEditor()->RegisterNotifyListener( this );
	Create( WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, rc, AfxGetMainWnd() );
}

CAssetBrowserDialog::~CAssetBrowserDialog()
{
	GetIEditor()->UnregisterNotifyListener( this );
	s_poCurrentInstance = NULL;
	// Disable the visual budget system and the detailed analysis mode if enabled.
	m_roVisualBudgetSystem.SetDetailedAnalysisStatus( false );

	CViewport* poViewport = GetIEditor()->GetViewManager()->GetViewport( "Perspective" );
	
	if( poViewport )
	{
		if( poViewport->IsRenderListenerRegistered( &m_roVisualBudgetSystem ) )
		{
			poViewport->UnregisterRenderListener( &m_roVisualBudgetSystem );
		}
	}
}

void CAssetBrowserDialog::Command_ShowViewportSelection()
{
	CAssetBrowserDialog* pBrowser = (CAssetBrowserDialog*)GetIEditor()->FindView(ASSET_BROWSER_NAME);

	if (!pBrowser)
		pBrowser = (CAssetBrowserDialog*)GetIEditor()->OpenView(ASSET_BROWSER_NAME);

	if (!pBrowser)
		return;

	pBrowser->OnAssetBrowserFromViewportSelection();
}

void CAssetBrowserDialog::RegisterViewClass()
{
	GetIEditor()->GetClassFactory()->RegisterClass( new CAssetBrowserViewClass );

	GetIEditor()->GetCommandManager()->RegisterCommand("AssetBrowser.ShowViewportSelection", functor(Command_ShowViewportSelection));
}

void CAssetBrowserDialog::OnEditorNotifyEvent( EEditorNotifyEvent event )
{
	if( event == eNotify_OnIdleUpdate )
	{
		return;
	}

	switch( event )
	{
		case eNotify_OnQuit: // Send when the document is about to close.
		{
			GetIEditor()->UnregisterNotifyListener( this );
			m_oAssetViewer.UnregisterObserver( this );
			m_oAssetViewer.WaitThreadAndFreeData();
			FreeDatabases();
			break;
		}
		case eNotify_OnCloseScene: // Send when the document is about to close.
		case eNotify_OnBeginSceneOpen: // Sent when document is about to be opened.
		case eNotify_OnBeginNewScene: // Sent when the document is begin to be cleared.
		{
			m_oAssetViewer.LockAll();
			break;
		}

		//case eNotify_OnMissionChange: // Send when the current mission changes. I am not sure if this is necessary.
		case eNotify_OnEndSceneOpen: // Sent after document have been opened.
		case eNotify_OnEndNewScene: // Sent after the document have been cleared.
		{
			m_oAssetViewer.UnlockAll();
			m_oAssetViewer.RefreshAssetsUsedInLevel();
			break;
		}

		// Sent when document is about to be saved.
		case eNotify_OnBeginSceneSave:
		{
			m_oAssetViewer.LockAll();
			break;
		}

		// Sent after document have been saved.
		case eNotify_OnEndSceneSave:
		{
			m_oAssetViewer.UnlockAll();
			break;
		}
	}
}

CAssetBrowserDialog* CAssetBrowserDialog::GetCurrentInstance()
{
	return s_poCurrentInstance;
}

void CAssetBrowserDialog::GetSelectedItems( TAssetItems& rcpoSelectedItemArray )
{
	m_oAssetViewer.GetSelectedItems( rcpoSelectedItemArray );
}

void CAssetBrowserDialog::DoDataExchange( CDataExchange* pDX )
{
	CBaseFrameWnd::DoDataExchange( pDX );
}

BOOL CAssetBrowserDialog::OnInitDialog()
{
	__super::OnInitDialog();
	
	// all databases are checked to be visible by default
	for( size_t i = 0; i < AssetBrowser::kMaxDatabaseCount; ++i )
	{
		m_checkedVisibleDatabases[i] = TRUE;
	}

	m_vbsDisplayType = m_roVisualBudgetSystem.GetDisplayType();
	m_vbsResourceType = m_roVisualBudgetSystem.GetMeasuredResourceType();

	if( m_roVisualBudgetSystem.GetCellSize() == 64.0f )
		m_vbsCellSizeIndex = 1;
	else
	if( m_roVisualBudgetSystem.GetCellSize() == 32.0f )
		m_vbsCellSizeIndex = 2;
	else
		m_vbsCellSizeIndex = 0;

	m_bVbsAnalyzeSingleSector = m_roVisualBudgetSystem.GetDetailedAnalysisStatus() ? TRUE : FALSE;
	m_bVbsAccountTerrain = m_roVisualBudgetSystem.GetAccountTerrainStatus() ? TRUE : FALSE;
	m_bVbsAccountMiscelaneous = m_roVisualBudgetSystem.GetAccountMiscelaneousStatus() ? TRUE : FALSE;
	m_bVbsAccountVegetation = m_roVisualBudgetSystem.GetAccountVegetationStatus() ? TRUE : FALSE;
	m_bVbsAccountBrushes = m_roVisualBudgetSystem.GetAccountBrushStatus() ? TRUE : FALSE;
	m_bVbsAccountRoads = m_roVisualBudgetSystem.GetAccountRoadsStatus() ? TRUE : FALSE;
	m_bVbsAccountClouds = m_roVisualBudgetSystem.GetAccountCloudsStatus() ? TRUE : FALSE;
	m_bVbsAccountEntities = m_roVisualBudgetSystem.GetAccountEntitiesStatus() ? TRUE : FALSE;
	m_bVbsAccountDecals = m_roVisualBudgetSystem.GetAccountDecalsStatus() ? TRUE : FALSE;

	CreateAssetViewer();
	CVisualBudgetSystem::GetVisualBudgetSystem().SetAssetBrowserDialog(this);

	// We MUST use the ID AFX_IDW_STATUS_BAR if we are speaking about the status bar.
	// We also are reserving 2 slots into the status bar, for currently selected file path
	// AND current dataset size.
	UINT indicators[] =
	{
		AFX_IDW_STATUS_BAR,
		AFX_IDW_STATUS_BAR
	};

	m_oWindowStatusBar.Create( this, WS_CHILD|WS_VISIBLE|CBRS_BOTTOM);
	m_oWindowStatusBar.SetIndicators(indicators,2);

	char szCaption[512];

	sprintf(szCaption, "No selection"); //Placeholder info.
	m_oWindowStatusBar.SetPaneText( 0, szCaption );//Placeholder info.

	sprintf(szCaption, "Ready"); //Placeholder info.
	m_oWindowStatusBar.SetPaneText( 1, szCaption );//Placeholder info.

	//TODO: this dialog will be recycled into the asset tag editor
	//m_oVisualBudgetSystem.Create( CVisualBudgetSystemSettings::IDD, this );
	//CXTPDockingPane * pPane = CreateDockingPane( "Visual Budget", &m_oVisualBudgetSystem, IDC_BUDGET_PANE, CRect(0,0,220,200), dockRightOf);

	//if( pPane )
	{
	//	pPane->Hide();
	}

	CreateRibbonBar();
	m_oAssetListView.ClearVisibleItems();

	// start a timer to check when db is ready
	SetTimer( ID_ASSET_BROWSER_TIMER_CHECK_DB_INFO_LOADED, 200, NULL );

	return TRUE;
}

void CAssetBrowserDialog::CreateAssetViewer()
{
	m_oThumbsSplitter.CreateStatic( this, 2, 1, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN );
	m_oThumbsSplitter.SetSplitterStyle( XT_SPLIT_NOFULLDRAG | XT_SPLIT_NOSIZE | XT_SPLIT_NOBORDER );
	m_oThumbsSplitter.SetRowInfo( 0, 500, 0 );
	m_oThumbsSplitter.SetRowInfo( 1, AssetBrowser::kSearchEditDialogHeight, 0 );
		
	m_oAssetViewer.Create( 0, 0, 500, 600, &m_oThumbsSplitter );
	m_oAssetViewer.SetDlgCtrlID( m_oThumbsSplitter.IdFromRowCol( 0, 0 ) );
	m_oAssetViewer.SetOwner( this );
	m_oAssetViewer.RegisterObserver( this );

	m_searchDlg.m_pAssetBrowserDlg = this;
	m_searchDlg.m_bForceFilterUsedInLevel = gSettings.sAssetBrowserSettings.bShowUsedInLevel;
	m_searchDlg.m_bForceShowFavourites = gSettings.sAssetBrowserSettings.bShowFavourites;
	m_searchDlg.m_bForceHideLods = gSettings.sAssetBrowserSettings.bHideLods;
	m_searchDlg.Create( CAssetBrowserSearchDlg::IDD, &m_oThumbsSplitter );
	m_searchDlg.SetDlgCtrlID( m_oThumbsSplitter.IdFromRowCol( 1, 0 ) );
	m_searchDlg.ShowWindow( SW_SHOW );

	m_oAssetListView.Create( WS_CHILD|WS_VISIBLE, CRect( 0, 0, 0, 0 ), this, 0 );
	m_assetPreviewDlg.Create( CAssetBrowserPreviewDlg::IDD, this );

	m_pDockPanePreview = CreateDockingPane( "Asset Preview", &m_assetPreviewDlg, IDW_ASSET_BROWSER_PREVIEW_PANE, CRect(0,0,550,300), dockLeftOf );
	m_pDockPanePreview->SetOptions(xtpPaneNoCloseable);
	m_pDockPaneListView = CreateDockingPane( "Asset List", &m_oAssetListView, IDW_ASSET_BROWSER_LIST_VIEW_PANE, CRect(0,0,550,300), dockBottomOf, m_pDockPanePreview );
	m_pDockPaneListView->SetOptions(xtpPaneNoCloseable);

	GetDockingPaneManager()->RecalcFramesLayout();
	ResizeSplitterPanes();
	CreateDatabases();
}

void CAssetBrowserDialog::CreateDatabases()
{
	size_t										nTotalDatabases = 0, nCurrentDatabase = 0;
	std::vector<IClassDesc*>	cAssetDatabasePlugins;
	IEditorClassFactory*			piClassFactory = NULL;
	IAssetDisplayDatabase*		piCurrentDatabaseInterface = NULL;

	m_oAssetViewer.WaitThreadAndFreeData();

	piClassFactory = GetIEditor()->GetClassFactory();
	piClassFactory->GetClassesByCategory( "Asset Display", cAssetDatabasePlugins );
	nTotalDatabases = cAssetDatabasePlugins.size();
	m_cAssetDatabases.clear();

	for( nCurrentDatabase = 0; nCurrentDatabase < nTotalDatabases; ++nCurrentDatabase )
	{
		if( cAssetDatabasePlugins[nCurrentDatabase]->QueryInterface( __uuidof(IAssetDisplayDatabase), (void**)&piCurrentDatabaseInterface ) == S_OK )
		{
			piCurrentDatabaseInterface->AddRef();
			piCurrentDatabaseInterface->SetAssociatedViewer( &m_oAssetViewer );
			m_cAssetDatabases.push_back( piCurrentDatabaseInterface );
		}
	}

	m_oAssetListView.ClearVisibleItems();
	m_oAssetViewer.SetDatabases( m_cAssetDatabases );
	m_oAssetViewer.RefreshDatabases();
	m_assetPreviewDlg.m_pAssetDisplay = NULL;
	m_assetPreviewDlg.m_pAssetPreviewDlg = NULL;
	m_assetPreviewDlg.RedrawWindow();
	m_nonThreadedAssetsCrtCount = 0;
	ResetAssetListView();
	m_oAssetViewer.RestartThread();
}

void CAssetBrowserDialog::FreeDatabases()
{
	size_t nCurrentDatabase = 0, nTotalDatabases = 0;
	m_oAssetViewer.WaitThreadAndFreeData();

	if( m_pAssetVirtualRecord )
	{
		m_pAssetVirtualRecord->m_pAssets = NULL;
	}

	for (size_t i = 0; i < m_cAssetDatabases.size(); ++i)
	{
		Log("Freeing asset database %s", m_cAssetDatabases[i]->GetDatabaseName());
		m_cAssetDatabases[i]->FreeData();
	}

	m_cAssetDatabases.clear();
}

void CAssetBrowserDialog::SortAssets( const char* pFieldname, bool bDescending )
{
	m_oAssetViewer.SortAssets( pFieldname, bDescending );
}

IAssetDisplayDatabase* CAssetBrowserDialog::GetDatabaseByName( const char* pName )
{
	for( size_t i = 0, iCount = m_cAssetDatabases.size(); i < iCount; ++i )
	{
		if( !stricmp( m_cAssetDatabases[i]->GetDatabaseName(), pName ) )
		{
			return m_cAssetDatabases[i];
		}
	}

	return NULL;
}

void CAssetBrowserDialog::ResetAssetListView()
{
	m_oAssetListView.m_pAssetBrowserDlg = this;

	// clear old columns
	if( m_oAssetListView.GetColumns() )
	{
		m_oAssetListView.GetColumns()->Clear();
	}

	m_pReportHeader = new CAssetListReportHeader( this, &m_oAssetListView, m_oAssetListView.GetColumns() );
	m_oAssetListView.SetReportHeader( m_pReportHeader );

	TAssetDatabases	visibleAssetDatabases = m_oAssetViewer.GetDatabases();

	if( !visibleAssetDatabases.size() )
	{
		return;
	}

	//
	// merge all fields from all the selected databases
	//
	m_allFields.clear();
	std::set<CString> insertedFieldnames;

	for( size_t i = 1, iCount = visibleAssetDatabases.size(); i < iCount; ++i )
	{
		IAssetDisplayDatabase::TAssetFields& fields = visibleAssetDatabases[i]->GetAssetFields();

		for( IAssetDisplayDatabase::TAssetFields::iterator iter = fields.begin(), iterEnd = fields.end(); iter != iterEnd; ++iter )
		{
			if( insertedFieldnames.end() == insertedFieldnames.find( iter->m_fieldName ) )
			{
				m_allFields.push_back( *iter );
			}
		}
	}

	//
	// find the common fields to all selected databases
	//
	IAssetDisplayDatabase::TAssetFields& firstDbFields = visibleAssetDatabases[0]->GetAssetFields();

	m_commonFields.clear();

	for( IAssetDisplayDatabase::TAssetFields::iterator iter = firstDbFields.begin(), iterEnd = firstDbFields.end(); iter != iterEnd; ++iter )
	{
		bool bAddField = true;

		for( size_t i = 1, iCount = visibleAssetDatabases.size(); i < iCount; ++i )
		{
			IAssetDisplayDatabase::TAssetFields& fields = visibleAssetDatabases[i]->GetAssetFields();

			// if field was not found, then do not add it, and exit from the loop
			if( !visibleAssetDatabases[i]->GetAssetFieldByName( iter->m_fieldName ) )
			{
				bAddField = false;
				break;
			}
		}

		if( bAddField )
		{
			m_commonFields.push_back( *iter );
		}
	}

	//
	// create columns from fields
	//
	size_t index = 0;

	// if we show all the fields in the list
	if( m_bShowMergedDatabaseFields )
	{
		for( IAssetDisplayDatabase::TAssetFields::iterator iter = m_allFields.begin(), iterEnd = m_allFields.end(); iter != iterEnd; ++iter )
		{
			m_oAssetListView.AddColumn( new CXTPReportColumn( index++, iter->m_displayName, iter->m_fieldName, iter->m_listColumnWidth, TRUE, XTP_REPORT_NOICON, TRUE, TRUE ) );
		}
	}
	else
	// show only the common fields to all databases
	{
		for( IAssetDisplayDatabase::TAssetFields::iterator iter = m_commonFields.begin(), iterEnd = m_commonFields.end(); iter != iterEnd; ++iter )
		{
			m_oAssetListView.AddColumn( new CXTPReportColumn( index++, iter->m_displayName, iter->m_fieldName, iter->m_listColumnWidth, TRUE, XTP_REPORT_NOICON, TRUE, TRUE ) );
		}
	}

	//
	// set virtual mode for the list
	//

	// workaround for XTP deleting the pointer
	m_oAssetListView.SetVirtualMode( new CXTPReportRecord(), 0 );
	m_pAssetVirtualRecord = new CAssetListVirtualRecord( this, &m_oAssetViewer.GetAssetItems() );
	// set our virtual record
	m_oAssetListView.SetVirtualMode( m_pAssetVirtualRecord, m_oAssetViewer.GetAssetItems().size(), m_bShowMergedDatabaseFields ? m_allFields.size() : m_commonFields.size() );
	
	if( m_oAssetListView.GetReportHeader() )
	{
		m_oAssetListView.GetReportHeader()->AllowColumnSort( TRUE );
	}

	m_oAssetListView.Populate();
}

void CAssetBrowserDialog::ShowOnlyCheckedDatabases()
{
	m_oAssetViewer.WaitThreadAndFreeData();

	if( m_pAssetVirtualRecord )
	{
		m_pAssetVirtualRecord->m_pAssets = NULL;
	}

	TAssetDatabases dbs;

	for( size_t i = 0, iCount = m_cAssetDatabases.size(); i < iCount; ++i )
	{
		if( m_checkedVisibleDatabases[i] )
		{
			dbs.push_back( m_cAssetDatabases[i] );
		}
	}

	m_oAssetViewer.SetDatabases( dbs );
	m_oAssetListView.ClearVisibleItems();
	ResetAssetListView();
	m_oAssetViewer.RestartThread();
	m_oAssetViewer.RecalculateTotalAssetCount();
	m_assetPreviewDlg.m_pAssetDisplay = NULL;
	m_assetPreviewDlg.m_pAssetPreviewDlg = NULL;
	m_assetPreviewDlg.RedrawWindow();
	// begin filtering
	m_searchDlg.SetTimer( ID_TIMER_SEARCH_BY_FILENAME, AssetBrowser::kSearchByFilenameTimerDelay, NULL );
}

void CAssetBrowserDialog::ApplyFilters( IAssetDisplayDatabase::TAssetFieldFiltersMap& rFilterFields )
{
	m_oAssetViewer.ApplyFilters( rFilterFields );

	// set our virtual record
	// workaround for XTP deleting the pointer
	m_oAssetListView.SetVirtualMode( new CXTPReportRecord(), 0 );
	m_pAssetVirtualRecord = new CAssetListVirtualRecord( this, &m_oAssetViewer.GetAssetItems() );
	m_oAssetListView.SetVirtualMode( m_pAssetVirtualRecord, m_oAssetViewer.GetAssetItems().size(), m_bShowMergedDatabaseFields ? m_allFields.size() : m_commonFields.size() );
	m_oAssetListView.GetReportHeader()->AllowColumnSort( TRUE );
	m_oAssetListView.Populate();
	m_oAssetListView.ClearVisibleItems();
}

void CAssetBrowserDialog::ClearFilters()
{
	m_oAssetViewer.ClearFilters();

	// set our virtual record
	// workaround for XTP deleting the pointer
	m_oAssetListView.SetVirtualMode( new CXTPReportRecord(), 0 );
	m_pAssetVirtualRecord = new CAssetListVirtualRecord( this, &m_oAssetViewer.GetAssetItems() );
	m_oAssetListView.SetVirtualMode( m_pAssetVirtualRecord, m_oAssetViewer.GetAssetItems().size(), m_bShowMergedDatabaseFields ? m_allFields.size() : m_commonFields.size() );
	m_oAssetListView.GetReportHeader()->AllowColumnSort( TRUE );
	m_oAssetListView.Populate();
	m_oAssetListView.ClearVisibleItems();
}

void CAssetBrowserDialog::UpdateAssetDatabaseForVisualBudgetSystem( const std::vector<AABB>& AABBs )
{
	CResourceCollector* pRC = CVisualBudgetSystem::GetVisualBudgetSystem().CalculateMapResourceMemoryUsage( AABBs );
	size_t nTotalDatabases = m_cAssetDatabases.size();

	for( size_t nCurrentDatabase = 0; nCurrentDatabase < nTotalDatabases; ++nCurrentDatabase )
	{
		m_cAssetDatabases[nCurrentDatabase]->SetAssociatedViewer( &m_oAssetViewer );
	}

	CString name;
	size_t assetCount = pRC->GetNumberOfAssets();

	for( size_t i = 0; i < assetCount; ++i )
	{
		pRC->GetAssetName( i, name );
		CString fileExt = Path::GetExt( CString( name ) );

		for( size_t nCurrentDatabase = 0; nCurrentDatabase < nTotalDatabases; ++nCurrentDatabase )
		{
			// if this database supports our file type, then specify we want this asset to be shown
			if( !stricmp( m_cAssetDatabases[nCurrentDatabase]->GetDatabaseTypeExt(), fileExt ) )
			{
				size_t size = GetIEditor()->GetSystem()->GetIPak()->FGetSize( name );
				//TODO: m_cAssetDatabases[nCurrentDatabase]->AddItem(CString(name), size);
				break;
			}
		}
	}
}

CAssetViewer& CAssetBrowserDialog::GetAssetViewer()
{
	return m_oAssetViewer;
}

void CAssetBrowserDialog::StartCacheAssetInfo()
{
	//TODO: fix asset info caching
	return;
	if( CAssetMetaDataFileDB::IsCachingInfoDone() )
	{
		m_oAssetViewer.CachingStarted();
		
		if( AssetBrowser::kAssetMetadataCachingIsOnThread )
		{
			SetTimer( ID_ASSET_BROWSER_TIMER_UPDATE_CACHING_PROGRESS, 50, NULL );
		}
		
		CAssetMetaDataFileDB::StartCachingInfo( AssetBrowser::kAssetMetadataCachingIsOnThread );
	}
}

void CAssetBrowserDialog::StopCacheAssetInfo()
{
	KillTimer( ID_ASSET_BROWSER_TIMER_UPDATE_CACHING_PROGRESS );
	CAssetMetaDataFileDB::AbortCachingInfo();
	m_oAssetViewer.CachingEnded();
}


void CAssetBrowserDialog::OnDestroy()
{
	__super::OnDestroy();
}

static bool s_bAllowDeleteThis = true;
static bool s_bPostDeleteAssetBrowserDlg = false;

void CAssetBrowserDialog::PostNcDestroy()
{
	s_poCurrentInstance = NULL;

	if( !s_bAllowDeleteThis )
	{
		s_bPostDeleteAssetBrowserDlg = true;
		return;
	}

	CAssetMetaDataFileDB::AbortLoadAndUpdate();
	CAssetMetaDataFileDB::AbortCachingInfo();
	FreeDatabases();
	m_oVisualBudgetSystem.DestroyWindow();
	m_oAssetViewer.UnregisterObserver( this );
	CVisualBudgetSystem::GetVisualBudgetSystem().SetAssetBrowserDialog( 0 );
	__super::PostNcDestroy();
}

void CAssetBrowserDialog::OnClose()
{	
	DestroyWindow();
}

BOOL CAssetBrowserDialog::PreTranslateMessage( MSG* pMsg )
{
	if( pMsg->message == WM_MOUSEWHEEL )
	{
		CWnd* poChildWindow = WindowFromPoint( pMsg->pt );

		if( poChildWindow == &m_oAssetViewer )
		{
			::SendMessage( m_oAssetViewer.GetSafeHwnd(), pMsg->message, pMsg->wParam, pMsg->lParam );
			return TRUE;
		}		
	}
	else
	if( pMsg->message == WM_KEYDOWN )
	{
			::SendMessage( m_oAssetViewer.GetSafeHwnd(), pMsg->message, pMsg->wParam, pMsg->lParam );

			return TRUE;
	}
	else
	if( pMsg->message == WM_KEYUP )
	{
		UINT nChar = pMsg->wParam;
		UINT nRepCnt = LOWORD( pMsg->lParam );
		UINT nFlags = HIWORD( pMsg->lParam );

		OnKeyDown(nChar, nRepCnt, nFlags);

		if( s_bPostDeleteAssetBrowserDlg )
		{
			if( m_hWnd )
			{
				CloseWindow();
				DestroyWindow();
			}

			CAssetMetaDataFileDB::AbortLoadAndUpdate();
			CAssetMetaDataFileDB::AbortCachingInfo();
			FreeDatabases();
			m_oVisualBudgetSystem.DestroyWindow();
			m_oAssetViewer.UnregisterObserver( this );
			CVisualBudgetSystem::GetVisualBudgetSystem().SetAssetBrowserDialog( 0 );
			delete this;
			s_bPostDeleteAssetBrowserDlg = false;
			return TRUE;
		}
	}

	return __super::PreTranslateMessage( pMsg );
}

void CAssetBrowserDialog::CreateRibbonBar()
{
	CXTPCommandBars* pCommandBars = GetCommandBars();
	CXTPToolBar* pEditToolBar = pCommandBars->Add( _T(ASSET_BROWSER_NAME), xtpBarTop );
	pEditToolBar->SetVisible( FALSE );
	pEditToolBar->EnableCustomization(FALSE);
	AfxEnableControlContainer();
	CXTPWinDwmWrapper().SetProcessDPIAware();

	// tooltips
	CXTPToolTipContext* pToolTipContext = GetCommandBars()->GetToolTipContext();

	pToolTipContext->ShowTitleAndDescription();
	pToolTipContext->SetMargin( CRect( 2, 2, 2, 2 ) );
	pToolTipContext->SetMaxTipWidth( 180 );
	pToolTipContext->SetFont( pCommandBars->GetPaintManager()->GetIconFont() );
	pCommandBars->GetCommandBarsOptions()->ShowKeyboardCues( xtpKeyboardCuesShowWindowsDefault );
	pCommandBars->GetCommandBarsOptions()->bToolBarAccelTips = TRUE;
	GetCommandBars()->GetPaintManager()->m_bEnableAnimation = TRUE;
	m_pRibbonBar = (CXTPRibbonBar*)pCommandBars->Add( _T("The Asset Browser Ribbon"), xtpBarTop, RUNTIME_CLASS(CXTPRibbonBar) );

	if( m_pRibbonBar )
	{
		m_pRibbonBar->SetCommandBars( pCommandBars );
		m_pRibbonBar->EnableDocking( FALSE );
		m_pRibbonBar->GetControls()->CreateOriginalControls();
		m_pRibbonBar->AddSystemButton( 0 );
		m_pRibbonBar->GetSystemButton()->SetHideFlag( xtpHideGeneric, true );

		m_dynamicRibbonBarLoader.Init( m_pRibbonBar );
#if defined(IS_CRYDEV) || defined(IS_LIMITED_SANDBOX)
		m_dynamicRibbonBarLoader.LoadFromFile( "Editor/UI/AssetBrowserRibbonFreeSDK.xml" );
#else
		m_dynamicRibbonBarLoader.LoadFromFile( "Editor/UI/AssetBrowserRibbon.xml" );
#endif
		UpdateRibbonButtons();
	}
}

void CAssetBrowserDialog::UpdateRibbonButtons()
{
	if( !m_pRibbonBar )
		return;

	CXTPRibbonTab* pTab = m_pRibbonBar->FindTab( ID_ASSET_BROWSER_RIBBON_TAB );
	
	if( pTab )
	{
		CXTPControl* pCtrl = NULL;
		CXTPRibbonGroup* pGrp = pTab->FindGroup( ID_ASSET_BROWSER_DATABASES_RIBBON_GROUP );

		if( pGrp )
		{
			for( size_t i = 0, iCount = m_cAssetDatabases.size(); i < iCount; ++i )
			{
				pCtrl = pGrp->Add( xtpControlCheckBox, ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_START + i );
				
				if( !i )
				{
					pCtrl->SetBeginGroup( TRUE );
				}

				pCtrl->SetCaption( m_cAssetDatabases[i]->GetDatabaseName() );
				pCtrl->SetChecked( TRUE );
				pCtrl->SetEnabled( TRUE );
			}
		}

		pGrp = pTab->FindGroup( ID_ASSET_BROWSER_VIEW_RIBBON_GROUP );

		if( pGrp )
		{
			pCtrl = pGrp->FindControl( ID_ASSET_BROWSER_THUMB_SIZE );

			if( pCtrl )
			{
				m_pCbThumbSize = (CXTPControlComboBox*)pCtrl;
				
				m_pCbThumbSize->ResetContent();
				m_pCbThumbSize->AddString( "16" );
				m_pCbThumbSize->AddString( "32" );
				m_pCbThumbSize->AddString( "64" );
				m_pCbThumbSize->AddString( "128" );
				m_pCbThumbSize->AddString( "256" );
				m_pCbThumbSize->AddString( "512" );
				m_pCbThumbSize->AddString( "1024" );
				m_pCbThumbSize->SetEnabled( TRUE );
				m_pCbThumbSize->SetWidth( 120 );
				m_pCbThumbSize->SetDropDownListStyle( FALSE );

				// used to match size to index of combo list thumb size item
				std::map<int,int> sizeToIndex;
				sizeToIndex[16] = 0;
				sizeToIndex[32] = 1;
				sizeToIndex[64] = 2;
				sizeToIndex[128] = 3;
				sizeToIndex[256] = 4;
				sizeToIndex[512] = 5;
				sizeToIndex[1024] = 6;
				sizeToIndex[2048] = 7;
				m_pCbThumbSize->SetCurSel( sizeToIndex[gSettings.sAssetBrowserSettings.nThumbSize] );
			}
		}

		pGrp = pTab->FindGroup( ID_ASSET_BROWSER_FILTERS_RIBBON_GROUP );

		m_pChkUsedInLevel = (CXTPControlCheckBox*)pGrp->FindControl( ID_ASSET_BROWSER_SHOW_USED_IN_LEVEL );
		m_pChkLoadedInLevel = (CXTPControlCheckBox*)pGrp->FindControl( ID_ASSET_BROWSER_SHOW_LOADED_IN_LEVEL );
		m_pChkShowFavourites = (CXTPControlCheckBox*)pGrp->FindControl( ID_ASSET_BROWSER_SHOW_FAVOURITES );

		//TODO: is this control really needed ?
		pCtrl = pGrp->FindControl( ID_ASSET_BROWSER_EDIT_TAGS );

		if( pCtrl )
		{
			CXTPControlEdit* pEdit = (CXTPControlEdit*) pCtrl;

			pEdit->SetWidth( 350 );
			pEdit->SetReadOnly( FALSE );
			pEdit->SetEditHint( "Type in the tag words separated by spaces" );
			pEdit->SetEnabled( TRUE );
		}
	}

	pTab = m_pRibbonBar->FindTab( ID_ASSET_BROWSER_VISUAL_BUDGET_SYSTEM_RIBBON_TAB );

	if( pTab )
	{
		CXTPControl* pCtrl = NULL;
		CXTPRibbonGroup* pGrp = pTab->FindGroup( ID_VISUAL_BUDGET_VIEW_TAB_GROUP );

		if( pGrp )
		{
			pCtrl = pGrp->FindControl( ID_VISUAL_BUDGET_CELL_SIZE );

			if( pCtrl )
			{
				m_pCbVbsCellSize = (CXTPControlComboBox*)pCtrl;

				m_pCbVbsCellSize->ResetContent();
				m_pCbVbsCellSize->AddString( "128" );
				m_pCbVbsCellSize->AddString( "64" );
				m_pCbVbsCellSize->AddString( "32" );
				m_pCbVbsCellSize->SetEnabled( TRUE );
				m_pCbVbsCellSize->SetDropDownListStyle( FALSE );
				m_pCbVbsCellSize->SetCurSel( m_vbsCellSizeIndex );
			}
		}
	}

	UpdateFilterPresetsList();
}

void CAssetBrowserDialog::UpdateFilterPresetsList()
{
	m_filterPresets.clear();

	CAssetBrowserFilterPresetsDlg::LoadFieldFiltersPresets( m_filterPresets );

	if( !m_pRibbonBar )
		return;

	CXTPRibbonTab* pTab = m_pRibbonBar->FindTab( ID_ASSET_BROWSER_RIBBON_TAB );

	if( pTab )
	{
		CXTPControl* pCtrl = NULL;
		CXTPRibbonGroup* pGrp = pTab->FindGroup( ID_ASSET_BROWSER_FILTERS_RIBBON_GROUP );

		if( pGrp )
		{
			m_pCbFilterPresets = (CXTPControlComboBox*)pGrp->FindControl( ID_ASSET_BROWSER_FILTER_PRESETS );

			if( m_pCbFilterPresets )
			{
				m_pCbFilterPresets->ResetContent();
				m_pCbFilterPresets->AddString( AssetBrowser::kNoPresetText );

				for( CAssetBrowserFilterPresetsDlg::TPresetNameAndPresetMap::iterator iter = m_filterPresets.begin(), iterEnd = m_filterPresets.end(); iter != iterEnd; ++iter )
				{
					m_pCbFilterPresets->AddString( iter->first );
				}

				m_pCbFilterPresets->SetWidth( AssetBrowser::kFilterPresetsComboLengthInPixels );
				m_pCbFilterPresets->SetDropDownListStyle( FALSE );
			}
		}
	}
}

void CAssetBrowserDialog::OnTimer(UINT_PTR nIDEvent)
{
	if (ID_ASSET_BROWSER_TIMER_CHECK_DB_INFO_LOADED == nIDEvent)
	{
		if (CAssetMetaDataFileDB::IsLoadAndUpdateDone())
		{
			KillTimer(ID_ASSET_BROWSER_TIMER_CHECK_DB_INFO_LOADED);
			ApplyAllFiltering();
		}
	}

	__super::OnTimer(nIDEvent);
}

void CAssetBrowserDialog::OnChangeStatusBarInfo( UINT nSelectedItems, UINT nVisibleItems, UINT nTotalItems )
{
	if( !m_oWindowStatusBar.GetSafeHwnd() || !m_oAssetViewer.GetSafeHwnd() )
		return;

	CString str;

	if( !nSelectedItems )
	{
		str.Format( "No selection" );
	}
	else
	{
		float fTotalSize = 0;
		TAssetItems items;

		m_oAssetViewer.GetSelectedItems( items );

		for( size_t i = 0, iCount = items.size(); i < iCount; ++i )
		{
			fTotalSize += items[i]->GetFileSize();
		}

		CString strTotal;

		// if under a megabyte
		if( fTotalSize < AssetBrowser::kOneMegaByte )
		{
			strTotal.Format( "%.1f KB", (float)fTotalSize / AssetBrowser::kOneKiloByte );
		}
		else
		{
			strTotal.Format( "%.2f MB", ASSET_BROWSER_BYTES_TO_MBYTES( fTotalSize ) );
		}

		str.Format( "%d selected assets, %s", nSelectedItems, strTotal.GetBuffer() );
	}

	m_oWindowStatusBar.SetPaneText( 0, str );

	str.Format( "%d listed assets, %d total assets", nVisibleItems, nTotalItems );
	m_oWindowStatusBar.SetPaneText( 1, str );
}

void CAssetBrowserDialog::OnSelectionChanged()
{
	if( !m_oAssetListView.GetSafeHwnd() )
		return;

	TAssetItems items;

	m_oAssetViewer.GetSelectedItems( items );

	int index = m_oAssetViewer.GetFirstSelectedItemIndex();
	
	if( !m_bSelectAssetsFromListView && index >= 0 && index < m_oAssetListView.GetRows()->GetCount() )
	{
		m_oAssetListView.GetRows()->GetAt(index)->EnsureVisible();
		m_oAssetListView.Recalc( TRUE );
		m_oAssetListView.RedrawWindow();
	}
	else
	{
		// ok, got it, set to false, we did not sent any select operation to the list
		m_bSelectAssetsFromListView = false;
	}
}

void CAssetBrowserDialog::OnChangedPreviewedAsset( IAssetDisplay* pAsset )
{
	CString str;

	// end the previous asset previewing, if any
	m_assetPreviewDlg.EndPreviewAsset();

	// begin preview the current one
	if( pAsset )
	{
		str.Format( "Asset Preview - [%s]", pAsset->GetFilename() );
		m_pDockPanePreview->SetTabCaption( str );
		m_pDockPanePreview->SetTitle( str );
	}
	else
	{
		str = "Asset Preview";
		m_pDockPanePreview->SetTabCaption( str );
		m_pDockPanePreview->SetTitle( str );
	}

	m_assetPreviewDlg.StartPreviewAsset( pAsset );
}

void CAssetBrowserDialog::ResizeSplitterPanes()
{
	if( !IsWindow( m_oThumbsSplitter.m_hWnd ) )
		return;

	// 2-row splitter, keep the bottom pane at fixed width
	int cxCur0, cxCur1, cxMin0, cxMin1;

	m_oThumbsSplitter.GetRowInfo( 0, cxCur0, cxMin0 );
	m_oThumbsSplitter.GetRowInfo( 1, cxCur1, cxMin1 );

	int totalHeight = cxCur0 + cxCur1;
	cxCur0 = MAX( totalHeight - AssetBrowser::kSearchEditDialogHeight, 0 );
	cxCur1 = AssetBrowser::kSearchEditDialogHeight;

	m_oThumbsSplitter.SetRowInfo( 0, abs( cxCur0 ), abs( cxMin0 ) );
	m_oThumbsSplitter.SetRowInfo( 1, abs( cxCur1 ), abs( cxMin1 ) );
	m_oThumbsSplitter.RecalcLayout();
}

void CAssetBrowserDialog::OnSize(UINT nType, int cx, int cy)
{
	__super::OnSize(nType, cx, cy);
	ResizeSplitterPanes();
}


void CAssetBrowserDialog::OnAssetBrowserDatabase( UINT id )
{
	UINT index = id - ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_START;
	
	if( index < AssetBrowser::kMaxDatabaseCount )
	{
		m_checkedVisibleDatabases[index] = !m_checkedVisibleDatabases[index];
		ShowOnlyCheckedDatabases();
	}
}

void CAssetBrowserDialog::OnUpdateAssetBrowserDatabase(CCmdUI* pCmdUI)
{
	UINT index = pCmdUI->m_nID - ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_START;
	
	if( index < AssetBrowser::kMaxDatabaseCount )
	{
		pCmdUI->SetCheck( m_checkedVisibleDatabases[index] );
		pCmdUI->Enable();
	}
}

void CAssetBrowserDialog::OnAssetBrowserDatabaseCheckAll()
{
	CXTPRibbonTab* pTab = m_pRibbonBar->FindTab( ID_ASSET_BROWSER_RIBBON_TAB );

	if( pTab )
	{
		CXTPControl* pC = NULL;

		for( size_t i = 0, iCount = pTab->FindGroup( ID_ASSET_BROWSER_DATABASES_RIBBON_GROUP )->GetCount(); i < iCount; ++i )
		{
			pC = pTab->FindGroup( ID_ASSET_BROWSER_DATABASES_RIBBON_GROUP )->GetAt( i );

			if( pC->GetID() >= ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_START && 
					pC->GetID() <= ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_END )
			{
				m_checkedVisibleDatabases[pC->GetID() - ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_START] = TRUE;
				pC->SetChecked( TRUE );
			}
		}

		ShowOnlyCheckedDatabases();
	}
}

void CAssetBrowserDialog::OnAssetBrowserDatabaseUncheckAll()
{
	CXTPRibbonTab* pTab = m_pRibbonBar->FindTab( ID_ASSET_BROWSER_RIBBON_TAB );

	if( pTab )
	{
		CXTPControl* pCtrl = NULL;

		for( size_t i = 0, iCount = pTab->FindGroup( ID_ASSET_BROWSER_DATABASES_RIBBON_GROUP )->GetCount(); i < iCount; ++i )
		{
			pCtrl = pTab->FindGroup( ID_ASSET_BROWSER_DATABASES_RIBBON_GROUP )->GetAt( i );

			if( pCtrl->GetID() >= ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_START && 
					pCtrl->GetID() <= ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_END )
			{
				m_checkedVisibleDatabases[pCtrl->GetID() - ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_START] = FALSE;
				pCtrl->SetChecked( FALSE );
			}
		}

		ShowOnlyCheckedDatabases();
	}
}

void CAssetBrowserDialog::OnAssetBrowserDatabaseRefresh()
{
	if( !CAssetMetaDataFileDB::IsLoadAndUpdateDone() )
		return;

	if( !CAssetMetaDataFileDB::IsCachingInfoDone() )
	{
		AfxMessageBox( "Please wait or cancel the full caching operation in progress, before refreshing the database(s)" );
		return;
	}

	m_oAssetViewer.RefreshDatabases();
	s_bAllowDeleteThis = false;
	s_bPostDeleteAssetBrowserDlg = false;
	StartCacheAssetInfo();
	s_bAllowDeleteThis = true;
	ApplyAllFiltering();
}

void CAssetBrowserDialog::OnAssetBrowserEditFilterPresets()
{
	CAssetBrowserFilterPresetsDlg dlg;

	dlg.m_pAssetBrowserDlg = this;
	dlg.DoModal();
	int crtIndex = m_pCbFilterPresets->GetCurSel();
	UpdateFilterPresetsList();
	m_pCbFilterPresets->SetCurSel( crtIndex > m_pCbFilterPresets->GetCount() ? m_pCbFilterPresets->GetCount() - 1 : crtIndex );
	ApplyAllFiltering();
}

void CAssetBrowserDialog::OnAssetBrowserChangeFilterPresets(NMHDR* pNMHDR, LRESULT* pResult)
{
	NMXTPCONTROL* tagNMCONTROL = (NMXTPCONTROL*)pNMHDR;
	CXTPControlComboBox* pControl = (CXTPControlComboBox*)tagNMCONTROL->pControl;
	
	if( pControl->GetType() == xtpControlComboBox )
	{
		ApplyAllFiltering();
	}
}

void CAssetBrowserDialog::OnAssetBrowserChangeThumbSize(NMHDR* pNMHDR, LRESULT* pResult)
{
	NMXTPCONTROL* tagNMCONTROL = (NMXTPCONTROL*)pNMHDR;
	CXTPControlComboBox* pControl = (CXTPControlComboBox*)tagNMCONTROL->pControl;

	if( pControl->GetType() == xtpControlComboBox )
	{
		int sel = pControl->GetCurSel();

		if( sel != CB_ERR )
		{
			UINT size = ( 1 << ( 4 + sel ) );
			m_oAssetViewer.SetAssetThumbSize( size );
		}
	}
}

void CAssetBrowserDialog::OnVisualBudgetChangeCellSize(NMHDR* pNMHDR, LRESULT* pResult)
{
	NMXTPCONTROL* tagNMCONTROL = (NMXTPCONTROL*)pNMHDR;
	CXTPControlComboBox* pControl = (CXTPControlComboBox*)tagNMCONTROL->pControl;

	if( pControl->GetType() == xtpControlComboBox )
	{
		int sel = pControl->GetCurSel();

		if( sel != CB_ERR )
		{
			m_vbsCellSizeIndex = sel;
			OnVisualBudgetUpdate();
		}
	}
}

void CAssetBrowserDialog::OnUpdateAssetBrowserCtrl(CCmdUI* pCmdUI)
{
	pCmdUI->Enable();
}

void CAssetBrowserDialog::ActivateFilterPreset( const char* pPresetName )
{
	if( !strcmp( pPresetName, "" ) )
	{
		m_searchDlg.m_fields.clear();
	}
	else
	{
		m_searchDlg.m_fields = m_filterPresets[pPresetName].m_fields;
	}

	std::set<CString> usedDatabaseNames;

	for( size_t i = 0, iCount = m_searchDlg.m_fields.size(); i < iCount; ++i )
	{
		if( m_searchDlg.m_fields[i].m_parentDatabaseName != "" )
		{
			usedDatabaseNames.insert( m_searchDlg.m_fields[i].m_parentDatabaseName );
		}
	}

	//
	// if there is not database name available in the filter fields, that means we have only common fields
	// so we will add all the database names, BUT ONLY WHEN A PRESET IS CHOSEN! otherwise we dont want to check/uncheck the databases
	//
	if( strcmp( pPresetName, "" ) )
	{
		if( usedDatabaseNames.empty() )
		{
			for( size_t i = 0, iCount = m_cAssetDatabases.size(); i < iCount; ++i )
			{
				usedDatabaseNames.insert( m_cAssetDatabases[i]->GetDatabaseName() );
			}
		}

		//
		// check or uncheck the ribbon checkboxes, and setup the databases
		//
		CXTPRibbonTab* pTab = m_pRibbonBar->FindTab( ID_ASSET_BROWSER_RIBBON_TAB );

		if( pTab )
		{
			CXTPControl* pCtrl = NULL;

			for( size_t i = 0, iCount = pTab->FindGroup( ID_ASSET_BROWSER_DATABASES_RIBBON_GROUP )->GetCount(); i < iCount; ++i )
			{
				pCtrl = pTab->FindGroup( ID_ASSET_BROWSER_DATABASES_RIBBON_GROUP )->GetAt( i );

				if( pCtrl->GetID() >= ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_START && pCtrl->GetID() <= ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_END )
				{
					BOOL bUsed = TRUE;
					UINT nDB = pCtrl->GetID() - ID_ASSET_BROWSER_DATABASE_CHECKBOX_ITEM_START;

					if( usedDatabaseNames.end() == usedDatabaseNames.find( m_cAssetDatabases[nDB]->GetDatabaseName() ) )
					{
						bUsed = FALSE;
					}

					m_checkedVisibleDatabases[nDB] = bUsed;
					pCtrl->SetChecked( bUsed );
				}
			}
		}
		else
		{
			AfxMessageBox( "Cannot find the tab for the asset browser" );
		}
	}

	ShowOnlyCheckedDatabases();
}

void CAssetBrowserDialog::OnAssetBrowserShowUsedInLevel()
{
	m_searchDlg.m_bForceFilterUsedInLevel = !m_searchDlg.m_bForceFilterUsedInLevel;
	gSettings.sAssetBrowserSettings.bShowUsedInLevel = m_searchDlg.m_bForceFilterUsedInLevel;
	m_oAssetViewer.RefreshAssetsUsedInLevel();
	ApplyAllFiltering();
}

void CAssetBrowserDialog::OnAssetBrowserShowFavourites()
{
	m_searchDlg.m_bForceShowFavourites = !m_searchDlg.m_bForceShowFavourites;
	gSettings.sAssetBrowserSettings.bShowFavourites = m_searchDlg.m_bForceShowFavourites;
	ApplyAllFiltering();
}

void CAssetBrowserDialog::OnAssetBrowserHideLods()
{
	m_searchDlg.m_bForceHideLods = !m_searchDlg.m_bForceHideLods;
	gSettings.sAssetBrowserSettings.bHideLods = m_searchDlg.m_bForceHideLods;
	ApplyAllFiltering();
}

void CAssetBrowserDialog::OnAssetBrowserRefreshUsedInLevel()
{
	m_oAssetViewer.RefreshAssetsUsedInLevel();
	ApplyAllFiltering();
}

void CAssetBrowserDialog::OnUpdateAssetBrowserUsedInLevel( CCmdUI* pUI )
{
	pUI->Enable();
	pUI->SetCheck( m_searchDlg.m_bForceFilterUsedInLevel );
}

void CAssetBrowserDialog::OnUpdateAssetBrowserShowFavourites( CCmdUI* pUI )
{
	pUI->Enable();
	pUI->SetCheck( m_searchDlg.m_bForceShowFavourites );
}

void CAssetBrowserDialog::OnUpdateAssetBrowserHideLods( CCmdUI* pUI )
{
	pUI->Enable();
	pUI->SetCheck( m_searchDlg.m_bForceHideLods );
}

void CAssetBrowserDialog::OnUpdateAssetBrowserAutoChangeViewportSelection( CCmdUI* pUI )
{
	pUI->Enable();
	pUI->SetCheck( m_bAutoChangeViewportSelection );
}

void CAssetBrowserDialog::OnUpdateAssetBrowserAutoFilterFromViewportSelection( CCmdUI* pUI )
{
	pUI->Enable();
	pUI->SetCheck( m_bAutoFilterFromViewportSelection );
}

void CAssetBrowserDialog::ApplyAllFiltering()
{
	CString strFilterName = "";

	if( m_pCbFilterPresets )
	{
		if( m_pCbFilterPresets->GetCount() && m_pCbFilterPresets->GetCurSel() != LB_ERR )
		{
			m_pCbFilterPresets->GetLBText( m_pCbFilterPresets->GetCurSel(), strFilterName );
		}
	}

	if( strFilterName == AssetBrowser::kNoPresetText )
	{
		strFilterName = "";
	}

	ActivateFilterPreset( strFilterName.GetBuffer() );
}

void CAssetBrowserDialog::OnAssetBrowserChangedEditTags()
{
	//TODO: changed edit tags
}

void CAssetBrowserDialog::OnAssetBrowserFromViewportSelection()
{
	// lets gather info about selection from viewport
	CSelectionGroup* pSelGrp = GetIEditor()->GetSelection();

	if( !pSelGrp )
	{
		AfxMessageBox( "No selection. Please select entities/objects in the viewport." );
		return;
	}

	m_searchDlg.m_bAllowOnlyFilenames = true;
	m_searchDlg.m_allowedFilenames = "";

	std::vector<CString> foundResources;

	for( size_t i = 0, iCount = pSelGrp->GetCount(); i < iCount; ++i )
	{
		CBaseObject* pObj = pSelGrp->GetObject( i );
		CUsedResources resUsed;

		pObj->GatherUsedResources( resUsed );

		for( CUsedResources::ResourceFiles::iterator iter = resUsed.files.begin(); iter != resUsed.files.end(); ++iter )
		{
			foundResources.push_back( *iter );
		}
	
		switch( pObj->GetType() )
		{
				case OBJTYPE_BRUSH:
				{
					CBrushObject* pBrush = (CBrushObject*)pObj;
					break;
				}

				case OBJTYPE_ENTITY:
				{
					CEntityObject* pEntity = (CEntityObject*)pObj;
					IEntity* pIEnt = pEntity->GetIEntity();

					for( size_t j = 0, jCount = pIEnt->GetSlotCount(); j < jCount; ++j )
					{
						//CEntityObject* pSlot = pEntity->GetSlot( j );

						//if( pSlot && pSlot->pStatObj )
						//{
						//	foundResources.insert( pSlot->pStatObj->GetFilePath() );
						//}
					}
					break;
				}
		}
	}

	JoinStrings<CString>( foundResources, m_searchDlg.m_allowedFilenames, ' ' );
	ApplyAllFiltering();
}

void CAssetBrowserDialog::OnAssetBrowserSelectInViewport()
{
	TAssetItems items;

	m_oAssetViewer.GetSelectedItems( items );
	GetIEditor()->ClearSelection();
	m_oAssetViewer.LockAll();

	CBaseObjectsArray objArr;

	GetIEditor()->GetObjectManager()->GetObjects( objArr );

	for( size_t i = 0, iCount = items.size(); i < iCount; ++i )
	{
		IAssetDisplay* pAsset = items[i];
		CString strFullPath = PathUtil::AddSlash( pAsset->GetRelativePath() ) + pAsset->GetFilename();

		for( size_t j = 0, jCount = objArr.size(); j < jCount; ++j )
		{
			CBaseObject* pObj = objArr[j];
			CUsedResources resUsed;

			pObj->GatherUsedResources( resUsed );

			for( CUsedResources::ResourceFiles::iterator iter = resUsed.files.begin(); iter != resUsed.files.end(); ++iter )
			{
				if( strFullPath == iter->GetString() )
				{
					GetIEditor()->SelectObject( pObj );
				}
			}

			switch( pObj->GetType() )
			{
				case OBJTYPE_BRUSH:
				{
					CBrushObject* pBrush = (CBrushObject*)pObj;
					break;
				}
			}
		}
	}
	
	m_oAssetViewer.UnlockAll();

	if( GetIEditor()->GetSelection() && !GetIEditor()->GetSelection()->GetCount() )
	{
		AfxMessageBox( "No objects were selected.\nNone of the selected assets is used by any of the level's objects." );
	}
}

void CAssetBrowserDialog::OnAssetBrowserAutoChangeViewportSelection()
{
	m_bAutoChangeViewportSelection = !m_bAutoChangeViewportSelection;
	gSettings.sAssetBrowserSettings.bAutoChangeViewportSelection = m_bAutoChangeViewportSelection;
}

void CAssetBrowserDialog::OnAssetBrowserAutoFilterFromViewportSelection()
{
	m_bAutoFilterFromViewportSelection = !m_bAutoFilterFromViewportSelection;
	gSettings.sAssetBrowserSettings.bAutoFilterFromViewportSelection = m_bAutoFilterFromViewportSelection;
}

void CAssetBrowserDialog::OnAssetBrowserClearViewportFilter()
{
	m_searchDlg.m_bAllowOnlyFilenames = false;
	ApplyAllFiltering();
}

void CAssetBrowserDialog::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	switch(nChar)
	{
		case VK_F5:
		{
			s_bAllowDeleteThis = false;
			s_bPostDeleteAssetBrowserDlg = false;
			StartCacheAssetInfo();
			s_bAllowDeleteThis = true;
			break;
		}
	}

	__super::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CAssetBrowserDialog::OnAssetBrowserConsoleHotUpdateFromSelection()
{
	TAssetItems selectedAssets;
	std::set<CString> files;

	m_oAssetViewer.GetSelectedItems( selectedAssets );

	for( size_t i = 0; i < selectedAssets.size(); ++i )
	{
		CString str;

		str = selectedAssets[i]->GetRelativePath();
		str += selectedAssets[i]->GetFilename();
		files.insert( str );
	}

	CConsoleHotUpdate::Instance().AddFiles( files );
}

void CAssetBrowserDialog::OnVisualBudgetUpdate()
{
	m_roVisualBudgetSystem.SetDetailedAnalysisStatus( m_bVbsAnalyzeSingleSector != FALSE );

	m_roVisualBudgetSystem.SetDisplayType( m_vbsDisplayType );
	m_roVisualBudgetSystem.SetMeasuredResourceType( CVisualBudgetSystem::ResourceType( m_vbsResourceType ) );

	if( m_vbsCellSizeIndex == 1 )
	{
		m_roVisualBudgetSystem.SetCellSize( 64.0f );
	}
	else
	if( m_vbsCellSizeIndex == 2 )
	{
		m_roVisualBudgetSystem.SetCellSize( 32.0f );
	}
	else
	{
		m_roVisualBudgetSystem.SetCellSize( 128.0f );
	}

	m_roVisualBudgetSystem.SetAccountTerrainStatus( m_bVbsAccountTerrain != FALSE );
	m_roVisualBudgetSystem.SetAccountMiscelaneousStatus( m_bVbsAccountMiscelaneous != FALSE );
	m_roVisualBudgetSystem.SetAccountBrushStatus( m_bVbsAccountBrushes != FALSE );
	m_roVisualBudgetSystem.SetAccountVegetationStatus( m_bVbsAccountVegetation != FALSE );
	m_roVisualBudgetSystem.SetAccountRoadsStatus( m_bVbsAccountRoads != FALSE );
	m_roVisualBudgetSystem.SetAccountCloudsStatus( m_bVbsAccountClouds != FALSE );
	m_roVisualBudgetSystem.SetAccountEntitiesStatus( m_bVbsAccountEntities != FALSE );
	m_roVisualBudgetSystem.SetAccountDecalsStatus( m_bVbsAccountDecals != FALSE );
	m_roVisualBudgetSystem.Update();
}

void CAssetBrowserDialog::OnVisualBudgetAnalyzeSingleSector()
{
	m_bVbsAnalyzeSingleSector = !m_bVbsAnalyzeSingleSector;
}

void CAssetBrowserDialog::OnVisualBudgetDisplaySectors()
{
	m_bVbsEnabledStatus = !m_bVbsEnabledStatus;

	if( m_bVbsEnabledStatus )
	{
		CViewport* poViewport = GetIEditor()->GetViewManager()->GetViewport( "Perspective" );
		
		if( poViewport )
		{
			if( !poViewport->IsRenderListenerRegistered( &m_roVisualBudgetSystem ) )
			{
				poViewport->RegisterRenderListener( &m_roVisualBudgetSystem );
			}
		}
	}
	else 
	{
		CViewport* poViewport = GetIEditor()->GetViewManager()->GetViewport( "Perspective" );
		
		if( poViewport )
		{
			if( poViewport->IsRenderListenerRegistered( &m_roVisualBudgetSystem ) )
			{
				poViewport->UnregisterRenderListener( &m_roVisualBudgetSystem );
			}
		}
	}

	OnVisualBudgetUpdate();
}

void CAssetBrowserDialog::OnUpdateVisualBudgetAnalyzeSingleSector( CCmdUI* pUI )
{
	pUI->Enable();
	pUI->SetCheck( m_bVbsAnalyzeSingleSector );
}

void CAssetBrowserDialog::OnUpdateVisualBudgetDisplaySectors( CCmdUI* pUI )
{
	pUI->Enable();
	pUI->SetCheck( m_bVbsEnabledStatus );
}

void CAssetBrowserDialog::OnUpdateVisualBudgetElement( CCmdUI* pUI )
{
	std::map<UINT,bool> elements;

	elements[ID_VISUAL_BUDGET_ELEMENT_TERRAIN] = m_bVbsAccountTerrain;
	elements[ID_VISUAL_BUDGET_ELEMENT_BRUSHES] = m_bVbsAccountBrushes;
	elements[ID_VISUAL_BUDGET_ELEMENT_VEGETATION] = m_bVbsAccountVegetation;
	elements[ID_VISUAL_BUDGET_ELEMENT_ROADS] = m_bVbsAccountRoads;
	elements[ID_VISUAL_BUDGET_ELEMENT_CLOUDS] = m_bVbsAccountClouds;
	elements[ID_VISUAL_BUDGET_ELEMENT_ENTITIES] = m_bVbsAccountEntities;
	elements[ID_VISUAL_BUDGET_ELEMENT_DECALS] = m_bVbsAccountDecals;
	elements[ID_VISUAL_BUDGET_ELEMENT_MISC] = m_bVbsAccountMiscelaneous;

	pUI->SetCheck( elements[pUI->m_nID] );
	pUI->Enable();
}


void CAssetBrowserDialog::OnVisualBudgetCheckElement( UINT id )
{
	std::map<UINT,BOOL*> elements;

	elements[ID_VISUAL_BUDGET_ELEMENT_TERRAIN] = &m_bVbsAccountTerrain;
	elements[ID_VISUAL_BUDGET_ELEMENT_BRUSHES] = &m_bVbsAccountBrushes;
	elements[ID_VISUAL_BUDGET_ELEMENT_VEGETATION] = &m_bVbsAccountVegetation;
	elements[ID_VISUAL_BUDGET_ELEMENT_ROADS] = &m_bVbsAccountRoads;
	elements[ID_VISUAL_BUDGET_ELEMENT_CLOUDS] = &m_bVbsAccountClouds;
	elements[ID_VISUAL_BUDGET_ELEMENT_ENTITIES] = &m_bVbsAccountEntities;
	elements[ID_VISUAL_BUDGET_ELEMENT_DECALS] = &m_bVbsAccountDecals;
	elements[ID_VISUAL_BUDGET_ELEMENT_MISC] = &m_bVbsAccountMiscelaneous;

	if( elements[id] )
	{
		*elements[id] = !(*elements[id]);
	}

	OnVisualBudgetUpdate();
}

void CAssetBrowserDialog::OnUpdateVisualBudgetDisplayMode( CCmdUI* pUI )
{
	bool bCheck = false;

	if( pUI->m_nID == ID_VISUAL_BUDGET_DISPLAY_LINES && m_vbsDisplayType == 0 )
	{
		bCheck = true;
	}
	else
	if( pUI->m_nID == ID_VISUAL_BUDGET_DISPLAY_BOXES && m_vbsDisplayType == 1 )
	{
		bCheck = true;
	}

	pUI->SetCheck( bCheck );
	pUI->Enable();
}

void CAssetBrowserDialog::OnVisualBudgetCheckDisplayMode( UINT id )
{
	if( id == ID_VISUAL_BUDGET_DISPLAY_LINES )
	{
		m_vbsDisplayType = 0;
	}
	else
	if( id == ID_VISUAL_BUDGET_DISPLAY_BOXES )
	{
		 m_vbsDisplayType = 1;
	}

	OnVisualBudgetUpdate();
}

void CAssetBrowserDialog::OnUpdateVisualBudgetResourceType( CCmdUI* pUI )
{
	bool bCheck = false;

	if( pUI->m_nID == ID_VISUAL_BUDGET_RESTYPE_GEOMETRY && m_vbsResourceType == 0 )
	{
		bCheck = true;
	}
	else
	if( pUI->m_nID == ID_VISUAL_BUDGET_RESTYPE_TEXTURES && m_vbsResourceType == 1 )
	{
		bCheck = true;
	}
	else
	if( pUI->m_nID == ID_VISUAL_BUDGET_RESTYPE_ALL && m_vbsResourceType == 2 )
	{
		bCheck = true;
	}

	pUI->SetCheck( bCheck );
	pUI->Enable();
}

void CAssetBrowserDialog::OnVisualBudgetCheckResourceType( UINT id )
{
	if( id == ID_VISUAL_BUDGET_RESTYPE_GEOMETRY )
	{
		m_vbsResourceType = 0;
	}
	else
	if( id == ID_VISUAL_BUDGET_RESTYPE_TEXTURES )
	{
		m_vbsResourceType = 1;
	}
	else
	if( id == ID_VISUAL_BUDGET_RESTYPE_ALL )
	{
		m_vbsResourceType = 2;
	}

	OnVisualBudgetUpdate();
}
